home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / vbccm68ksrc.lha / vbcc / vlink / t_elf32.c < prev    next >
C/C++ Source or Header  |  1999-03-07  |  59KB  |  1,836 lines

  1. /* $VER: vlink t_elf32.c V0.6d (13.02.99)
  2.  *
  3.  * This file is part of vlink, a portable linker for multiple
  4.  * object formats.
  5.  * Copyright (c) 1997-99  Frank Wille
  6.  *
  7.  * vlink is freeware and part of the portable and retargetable ANSI C
  8.  * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
  9.  * vlink may be freely redistributed as long as no modifications are
  10.  * made and nothing is charged for it. Non-commercial usage is allowed
  11.  * without any restrictions.
  12.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  13.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  14.  *
  15.  *
  16.  * v0.6d (13.02.98) phx
  17.  *       The PowerUp ELF loader has its own constructor/destructor
  18.  *       functionality and wildly mixes all words in .ctors and .dtors.
  19.  *       Have to rename the sections to .ctor_/.dtor_ for elf32powerup
  20.  *       executable generation.
  21.  * v0.6c (05.02.98) phx
  22.  *       Constructor/destructor support for vbcc's _INIT/_EXIT
  23.  *       function. The function pointers will be placed into the
  24.  *       the .ctors and .dtors sections.
  25.  * v0.6a (19.12.98) phx
  26.  *       Support for little endian object file formats.
  27.  * v0.6  (24.10.98) phx
  28.  *       Standard ELF32 linker symbols _SDA_BASE_ and _SDA2_BASE_
  29.  *       are supported. _SDA_BASE_ points to .sdata+0x7ff0 (or .sbss, if
  30.  *       .sdata is missing) and _SDA2_BASE_ (EABI only) to .sdata2+0x7ff0.
  31.  *       Take base register section offset from FFFuncs.baseoff. Each
  32.  *       target defines their own offsets.
  33.  *       .sdata/.sbss and .sdata2/.sbss2 will always be combined.
  34.  *       Linking with shared objects is possible. Creating them is
  35.  *       a another story...
  36.  *       New target elf32powerup. It is a elf32ppcbe-type target, which
  37.  *       uses relocatable objects as final executables. It is used for
  38.  *       the Amiga PowerUp turbo boards from Phase5, which have a special
  39.  *       ELF object loader. This loader will do some kind of dynamic
  40.  *       linking with functions from the PowerUp kernel.
  41.  *       _LinkerDB is no longer known to elf32ppcbe, but only to
  42.  *       elf32powerup.
  43.  * v0.5d (22.08.98) phx
  44.  *       Faster memory allocation can be activated by #define FASTALLOC.
  45.  * v0.5b (05.07.98) phx
  46.  *       Linker symbol _LinkerDB for elf32ppcbe. _LinkerDB is a reloc sym-
  47.  *       bol, which can be used to initialize a small data base register.
  48.  * v0.5  (27.06.98) phx
  49.  *       Target-specific linker symbol support: elf32_lnksym(),
  50.  *       elf32_setlnksym().
  51.  * v0.4  (05.06.98) phx
  52.  *       New FFF targetlink(). Currently no meaning for ELF.
  53.  * v0.3b (25.04.98) phx
  54.  *       Renamed from t_elf.c into t_elf32.c.
  55.  * v0.3  (17.04.98) phx
  56.  *       First version, which links and writes ELF PowerPC 32Bit big
  57.  *       endian objects (elf32ppcbe) reliable.
  58.  * v0.0  (21.03.98) phx
  59.  *       File created.
  60.  */
  61.  
  62.  
  63. #if defined(ELF32_PPC_BE) || defined(ELF32_PPC_LE) || defined(ELF32_POWERUP)
  64. #define T_ELF32_C
  65. #include "vlink.h"
  66. #include "elf32.h"
  67. #include "rel_elfppc.h"
  68.  
  69. #define ELF_VER 1
  70.  
  71.  
  72. #if defined(ELF32_PPC_BE) || defined(ELF32_POWERUP)
  73. static int ppc32be_identify(char*,uint8 *,unsigned long);
  74. static void ppc32be_readconv(struct GlobalVars *,struct LinkFile *);
  75. static void ppc32be_readELF(struct GlobalVars *,struct LinkFile *,uint8 *);
  76. static unsigned long ppc32be_secbase(struct GlobalVars *,char *);
  77. static uint8 ppc32be_cmpsecflags(uint8,uint8);
  78. static struct Section *ppc32be_bssdefault(struct ObjectUnit *);
  79. static int ppc32be_targetlink(struct GlobalVars *,struct LinkedSection *,
  80.                               struct Section *);
  81. static struct Symbol *ppc32be_lnksym(struct GlobalVars *,struct Section *,
  82.                                      struct XReference *);
  83. static void ppc32be_setlnksym(struct GlobalVars *,struct Symbol *,
  84.                               struct XReference *);
  85. static void ppc32be_relocs(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  86.                            struct Elf32_Shdr *);
  87. #endif
  88. #ifdef ELF32_PPC_BE
  89. static void ppc32be_writeobject(struct GlobalVars *,FILE *);
  90. static void ppc32be_writeshared(struct GlobalVars *,FILE *);
  91. static void ppc32be_writeexec(struct GlobalVars *,FILE *);
  92. static uint8 ppc32be_getrel(uint8,char *,uint32);
  93.  
  94. struct FFFuncs fff_elf32ppcbe = {
  95.   "elf32ppcbe",
  96.   ppc32be_identify,
  97.   ppc32be_readconv,
  98.   ppc32be_secbase,
  99.   ppc32be_cmpsecflags,
  100.   ppc32be_bssdefault,
  101.   ppc32be_targetlink,
  102.   ppc32be_lnksym,
  103.   ppc32be_setlnksym,
  104.   ppc32be_writeobject,
  105.   ppc32be_writeshared,
  106.   ppc32be_writeexec,
  107.   0x7ff0,
  108.   NULL,
  109.   1 /* big endian */
  110. };
  111. #endif
  112.  
  113.  
  114. #ifdef ELF32_POWERUP
  115. static struct Symbol *powerup_lnksym(struct GlobalVars *,struct Section *,
  116.                                      struct XReference *);
  117. static void powerup_setlnksym(struct GlobalVars *,struct Symbol *,
  118.                               struct XReference *);
  119. static void powerup_writeobject(struct GlobalVars *,FILE *);
  120. static void powerup_writeshared(struct GlobalVars *,FILE *);
  121. static void powerup_writeexec(struct GlobalVars *,FILE *);
  122. static uint8 powerup_getrel(uint8,char *,uint32);
  123.  
  124. struct FFFuncs fff_elf32powerup = {
  125.   "elf32powerup",
  126.   ppc32be_identify,
  127.   ppc32be_readconv,
  128.   ppc32be_secbase,
  129.   ppc32be_cmpsecflags,
  130.   ppc32be_bssdefault,
  131.   ppc32be_targetlink,
  132.   powerup_lnksym,
  133.   powerup_setlnksym,
  134.   powerup_writeobject,
  135.   powerup_writeshared,
  136.   powerup_writeexec,
  137.   0x7ff0,
  138.   NULL,
  139.   1 /* big endian */
  140. };
  141.  
  142.  
  143. /* elf32powerup linker symbols */
  144. static char *linkerdb = "_LinkerDB";
  145. #define LINKERDB        0   /* _LinkerDB, powerup */
  146. #endif
  147.  
  148.  
  149. /* elf32 common linker symbols */
  150. static char *elf32_symnames[] = {
  151.   "_SDA_BASE_","_SDA2_BASE_",".ctors",".dtors"
  152. };
  153. /* number of elf32 linker symbols */
  154. #define ELF32_LNKSYMS 4
  155.  
  156. /* Linker symbol IDs */
  157. #define SDABASE         0   /* _SDA_BASE_, elf32 */
  158. #define SDA2BASE        1   /* _SDA2_BASE_, elf32 */
  159. #define CTORS           2   /* .ctors */
  160. #define DTORS           3   /* .dtors */
  161.  
  162. /* small data sections */
  163. static char *sdata = ".sdata";
  164. static char *sbss = ".sbss";
  165. static char *sdata2 = ".sdata2";
  166. static char *sbss2 = ".sbss2";
  167.  
  168. /* automatic constructors and destructors (vbcc) */
  169. static char vbcc_INIT[] = "_INIT";
  170. static char vbcc_EXIT[] = "_EXIT";
  171. static char xtors_objname[] = "INITEXIT"; /* unit name for con/destructors */
  172.  
  173.  
  174. static int elf32be_identify(struct FFFuncs *,char *,struct Elf32_Ehdr *,
  175.                             unsigned long,unsigned char,unsigned char,
  176.                             uint16,uint32);
  177. static void elf32be_check_ar_type(struct FFFuncs *,char *,
  178.                                   struct Elf32_Ehdr *,unsigned char,
  179.                                   unsigned char,uint32,uint16,uint16,uint16);
  180. static char *elf32be_shstrtab(struct LinkFile *,struct Elf32_Ehdr *);
  181. static char *elf32be_strtab(struct LinkFile *,struct Elf32_Ehdr *,int);
  182. static struct Elf32_Sym *elf32be_symtab(struct LinkFile *,
  183.                                         struct Elf32_Ehdr *,int);
  184. static struct Elf32_Shdr *elf32be_shdr(struct LinkFile *lf,
  185.                                        struct Elf32_Ehdr *,uint16);
  186. static void elf32be_section(uint8 *,struct ObjectUnit *,
  187.                             struct Elf32_Shdr *,int);
  188. static int get_xtors_pri(char *);
  189. static void elf32be_symbols(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  190.                             struct Elf32_Shdr *);
  191. static void elf32be_reloc(struct GlobalVars *,struct Elf32_Ehdr *,
  192.                           struct Section *,uint32,struct Elf32_Rela *,
  193.                           bool,uint8);
  194. static struct Section *elf32be_bssdefault(struct ObjectUnit *);
  195. static int elf32_targetlink(struct GlobalVars *,struct LinkedSection *,
  196.                             struct Section *);
  197. static struct Symbol *elf32_lnksym(struct GlobalVars *,struct Section *,
  198.                                    struct XReference *,struct FFFuncs *);
  199. static void elf32_setlnksym(struct GlobalVars *,struct Symbol *,
  200.                             struct XReference *,struct FFFuncs *);
  201. static void elf32be_header(FILE *,uint16,uint16,uint32,uint32,uint32,
  202.                            uint32,uint16,uint16,uint16);
  203. static void elf32be_writeshdrs(FILE *,uint32,uint32);
  204. static void elf32be_stdsymtab(struct GlobalVars *,uint8,uint8);
  205. static void